
def matrix_to_string(M, padfunc=None):
    """Return a string representation of a matrix with each row on a new line, 
    and padding between columns determined by the optional padfunc argument. 
    If provided, padfunc must accept row and column indicies as input and produce 
    an int output.
    """
    rowstrs = []
    for i in range(len(M)):
        rowstr = ""
        if padfunc:
            for j in range(len(M[0])):
                rowstr = rowstr + repr(M[i][j]).rjust(padfunc(i,j))
        else:
            rowstr = repr(M[i])
        rowstrs.append(rowstr)
    return '\n'.join(rowstrs)

def print_matrix(M, padfunc=None):
    """Print a matrix with each row on a new line, and padding between columns
    determined by the optional padfunc argument. If provided, padfunc must 
    accept row and column indicies as input and produce an int output.
    """
    print(matrix_to_string(M, padfunc))